Exemplary embodiments of the present invention relate to compilation of software programs from code written in a source language to code written in a language executable by a target machine, and more particularly, to just-in-time compilation of software programs.
Java, which is used for a wide range of applications including games, pervasive devices, and critical e-business applications, is one of the most dominant programming languages. Because Java is an interpreted language, any programs written in Java, after being converted into Java class files containing Java bytecode (an architecture-neutral distribution format), are interpreted by a Java virtual machine (JVM) for each platform. In order to improve performance, many JVMs may compile Java classes into platform-specific binary code after they are loaded into the JVM. Then, instead of being interpreted, Java classes are executed in their compiled native code format, similar to programs written in other languages such as C, C++, etc, by converting the given bytecode sequences “on-the-fly” at runtime into an equivalent sequence of the native code for the underlying machine. Such just-in-time (JIT) compilation of Java programs can significantly improve the speed of execution of Java programs.
Nevertheless, the compilation time overhead of a JIT compiler, in contrast to that of a conventional static compiler, is included in the Java program execution time. Thus, for a given Java class method, JIT compilation can be justified only if the compiled method code executes in less time than the interpreted byte code for the method. Otherwise, the method should be executed by interpreting the method's bytecodes. For typical Java applications, there are many class methods that are only rarely invoked, making JIT compilation of such methods unjustified.
In advanced JVM implementations, JIT compilers compile Java methods selectively, depending upon the satisfaction of certain criteria. This so-called “hot-spot compiling” is a hybrid of interpretation and just-in-time compilation that attempts to combine both techniques in order to yield Java programs that run as fast as natively compiled code. An interpreter called a “mixed mode interpreter” may perform this type of execution in the execution engine. A mixed-mode interpreter attempts to analyze or profile the program in order to determine the locations of the program that justify the time expense for compiling a portion of the program.
The usual approach to optimization is to profile the program in a temporal dimension to discover exactly where the program spends most of its time, and then spend time optimizing portions of the program that execute most often. In this approach, the JVM begins the execution of the program by interpreting the program. As the JVM interprets the program's bytecodes, it analyzes the execution of the program to determine the program's “hot spots,” which is the part of the program where the program spends most of its time. When it identifies a hot spot, the JVM directs JIT compilation of only the portion of the code that encompasses the hot spot. The optimizations performed during JIT compilation, however, can be especially time intensive, and a moderate-sized Java program may execute millions of different bytecode sequences in which there are many bytecode sequences to optimize. Designers of JIT compilers must therefore trade off the time spent optimizing a bytecode sequence against the runtime gain from making that sequence faster.